/************************************************************************************
**  
* @copyright (c) 2013-2100,  Technology Co., LTD. All Right Reserved.
*
*************************************************************************************/
/**
* @file	    duye_sys_process.cpp
* @version     
* @brief      
* @author
* @date     2014-09-28
* @note 
*
*  1. 2014-09-28 Created this file
* 
*/
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/resource.h>

#include <duye_sys_process.h>

namespace duye {

static const uint32 DEF_LIMIT_FILE = 10240;

ProcessSysCallbackObserver* ProcessSysCallback::m_observer = NULL;

SysProcess::SysProcess() {
    setLimitFile(DEF_LIMIT_FILE);   	
}

SysProcess::~SysProcess() {}

bool SysProcess::setLimitFile(const uint32 limitFile) {
    m_limitFile = limitFile;
	
    struct rlimit rt;
    rt.rlim_max = rt.rlim_cur = m_limitFile;
    if (setrlimit(RLIMIT_NOFILE, &rt) == -1) {
        return false;
    }    	
    
    return true;
}

uint32 SysProcess::limitFile() const {
    return m_limitFile;	
}

ProcessSysCallback::ProcessSysCallback() {}

ProcessSysCallback::~ProcessSysCallback() {}

void ProcessSysCallback::registObserver(ProcessSysCallbackObserver* observer) {
    m_observer = observer;
}

void ProcessSysCallback::addSignal(const SysProcess::SignalType sig) {
    if (sig & SysProcess::D_SIGSEGV) {
        // segmentation fault
        signal(SIGSEGV, ProcessSysCallback::signalHandler);
        // printf("add signal SIGSEGV ok \n");
    }

    if (sig & SysProcess::D_SIGINT) {
        // ctrl + c
        signal(SIGINT, ProcessSysCallback::signalHandler);
        //printf("add signal SIGINT ok \n");
    }
}

void ProcessSysCallback::signalHandler(const int32 sig) {
    if (m_observer == NULL) {
    	return;
    }

	SysProcess::SignalType signalType = SysProcess::D_SIG;
	switch (sig) {
    	case SIGSEGV:
    		signalType = SysProcess::D_SIGSEGV;
    		break;
    	case SIGINT:
    		signalType = SysProcess::D_SIGINT;
    		break;
    	default:
    		signalType = SysProcess::D_SIG;
    		break;
	}
	
    m_observer->onSignalHandler(signalType);
}

}
